package com.bilibili.juc.forkjoin;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 斐波那契数列（Fibonacci sequence），也叫黄金分割数列，是一个非常经典的数学数列，其特点是每个数字都是前两个数字之和。通常以0和1作为数列的起始值，即F(1) = 0, F(2) = 1，然后根据这两个起始值计算后续的值。
 斐波那契数列的前几个数字如下：
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
 从第三项开始，每一项都等于前两项之和。例如，第三项1是前两项0和1之和，第四项2是前两项1和1之和，以此类推。
 */
public class FibonacciCalculator extends RecursiveTask<Long> {
    private final int n;

    public FibonacciCalculator(int n) {
        this.n = n;
    }

    @Override
    protected Long compute() {
        if (n <= 1) {
            return (long) n;
        } else {
            FibonacciCalculator f1 = new FibonacciCalculator(n - 1);
            FibonacciCalculator f2 = new FibonacciCalculator(n - 2);

            // Fork两个子任务
            f1.fork();
            f2.fork();

            // Join子任务的结果并合并
            return f1.join() + f2.join();
        }
    }

    /**
     * 在上述示例中，FibonacciCalculator继承了RecursiveTask<Long>，表示这是一个有返回值的任务。在compute方法中，我们根据递归的方式分割任务，
     * 然后使用fork方法启动子任务，最后使用join方法合并子任务的结果。
     * 在main方法中，我们创建了一个ForkJoinPool，然后使用invoke方法启动主任务，计算斐波那契数列的第N个数。
     * @param args
     */
    public static void main(String[] args) {
        int n = 2; // 计算斐波那契数列的第3个数

        ForkJoinPool pool = ForkJoinPool.commonPool(); // 创建Fork-Join池

        long result = pool.invoke(new FibonacciCalculator(n)); // 启动任务计算

        System.out.println("Fibonacci(" + n + ") = " + result);
    }
}